/*
 Copyright (c) [Year] [name of copyright holder]
 [Software Name] is licensed under Mulan PSL v2.
 You can use this software according to the terms and conditions of the Mulan
 PSL v2.
 You may obtain a copy of Mulan PSL v2 at:
          http://license.coscl.org.cn/MulanPSL2
 THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
 NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 See the Mulan PSL v2 for more details.
*/

#ifndef _1988WJ_PASTEIO_HPP_
#define _1988WJ_PASTEIO_HPP_

#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <mutex>
#include <regex>
#include <vector>

namespace fs = std::filesystem;

class PasteIO {
  private:
  public:
    /**
     * @brief 获取指定目录下的文件路径
     *
     * @param filesOut 输出的文件路径向量，将存储获取到的文件路径
     * @param dir 要获取文件路径的目录
     * @param extension 文件扩展名，如果为空则表示接受所有文件
     * @param isRecursive 是否递归遍历子目录
     *
     * 获取指定目录下的文件路径
     * 如果指定了扩展名，则只获取具有该扩展名的文件
     * 如果设置为递归模式，则会遍历子目录
     */
    static void GetFiles(std::vector<fs::path> &filesOut, const std::string &dir, const std::string &extension = "",
                         bool isRecursive = false);

    /**
     * @brief 将文本文件的内容读取到字符串列表中
     *
     * @param strListOut 输出参数，包含从文件中读取的字符串列表
     * @param filePath 文件路径
     * @param mode 文件打开模式
     *
     * 此函数尝试打开指定路径的文本文件，并将每一行内容读取到一个字符串列表中
     * 它会忽略行首和行尾的空白字符，并且如果一行在去除空白字符后为空，则忽略该行
     * 如果文件无法打开或读取过程中发生错误，函数将返回-1并输出错误信息
     */
    static void TextToList(std::vector<std::string> &strListOut, const std::string &filePath,
                           std::ios_base::openmode mode = std::ios_base::in | std::ios_base::binary);

    /**
     * @brief 将指定文件的文本内容读取到字符串变量中
     *
     * @param strOut 输出参数，将读取的文本内容存储在此变量中
     * @param filePath 输入参数，指定要读取文本的文件路径
     * @param mode 文件打开模式，例如标准输入输出流的打开方式
     *
     * 此函数打开指定路径的文件，并将文件中的所有文本内容读取到textOut参数中。
     * 如果文件无法打开或读取过程中发生错误，textOut将保持不变。
     */
    static void TextToString(std::string &strOut, const std::string &filePath,
                             std::ios_base::openmode mode = std::ios_base::in | std::ios_base::binary);

    /**
     * @brief 验证给定路径的有效性
     *
     * @param path 待验证的文件或目录路径
     * @param isDir 指示路径是否为目录的布尔值
     *
     * 验证给定路径是否有效，如果路径不为空且符合命名规则，则不执行任何操作；否则抛出异常。
     * 如果路径是要创建的文件的路径，则会确保其父目录存在，如果父目录不存在，则会尝试创建。
     */
    static void VerifyDir(const std::string &path, bool isDir);

    /**
     * @brief 将错误信息写入标准错误流,按任意建退出程序
     *
     * @param errorStr 错误信息字符串
     *
     * 此函数将错误信息写入标准错误流，并添加一个换行符
     */
    static void WriteError(const std::string &errorStr);

    /**
     * 将字符串内容保存到指定文件中
     *
     * @param saveStrStream 包含要保存字符串的stringstream对象
     * @param filePath 要保存到的文件路径
     * @param mode 文件打开模式，可选，默认为二进制读写
     *
     * 此函数负责将内存中的字符串内容写入到指定路径的文件中使用指定的文件打开模式
     * 如果文件路径不存在，函数将尝试创建新文件并写入内容
     * 如果文件路径已存在，根据提供的文件打开模式，函数将覆盖或附加内容到文件中
     */
    static void SaveStringToFile(const std::stringstream &saveStrStream, const std::string &filePath,
                                 std::ios_base::openmode mode = std::ios_base::out | std::ios_base::binary);

    static int MoveFileAndRename(const std::string &src, const std::string &dest);
};
#endif